package com.hardson.toolkit.util;

import java.io.*;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public final class StrUtil {

    public static final String DateFormat_yyyy_MM_dd = "%tF%n";

    public static final String DateFormat_HH_MM_SS = "%tT%n";

    public static final String DateFormat_yyyy_MM_dd_HH_MM_SS = "%tF%n %tT%n";

    private StrUtil() {
    }

    public static String gbk2Iso(String value) throws Exception {
        if (isTrimEmpty(value)) {
            return "";
        }
        return new String(value.getBytes("GBK"), StandardCharsets.ISO_8859_1);
    }

    public static String iso2GBK(String value) throws Exception {
        if (isTrimEmpty(value)) {
            return "";
        }
        return new String(value.getBytes(StandardCharsets.ISO_8859_1), "GBK");
    }

    public static List<String> split(String value, String subStr) {

        if (isTrimEmpty(value) || isTrimEmpty(subStr)) {
            return new ArrayList<>();
        }
        List<String> list = new ArrayList<>();
        int start = 0;
        int length = subStr.length();
        for (; ; ) {
            int index = value.indexOf(subStr, start);
            if (index == -1) {
                list.add(value.substring(start));
                break;
            }
            list.add(value.substring(start, index));
            start = index + length;
        }
        return list;
    }

    public static String trimEmpty(Object obj) {
        return Objects.toString(obj, "").trim();
    }

    public static boolean isTrimEmpty(Object obj) {
        return trimEmpty(obj).isEmpty();
    }

    public static boolean isNotTrimEmpty(Object obj) {
        return !isTrimEmpty(obj);
    }

    public static String clearWhiteSpace(String srcStr) {
        // \s 匹配任何空白字符，包括空格、制表符、换页符、中文空格等。与 [ \f\n\r\t\v　] 等效。
        return srcStr.replaceAll("[\\s　]", "");
    }

    public static byte[] convertPass(char[] ac) {
        byte[] abyte0 = null;
        Charset charset = StandardCharsets.UTF_8;
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             OutputStreamWriter osw = new OutputStreamWriter(baos, charset)) {
            osw.write(ac);
            osw.flush();
            abyte0 = baos.toByteArray();
        } catch (IOException ie) {
            // IOException shall not be thrown
        }
        return abyte0;
    }

    public static byte[] sha1Digest(byte[] abyte0) {
        MessageDigest sha1 = null;
        try {
            sha1 = MessageDigest.getInstance("SHA");
            return sha1.digest(abyte0);
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalArgumentException("Error disgest bytes" + e.getMessage());
        }
    }

    public static String replace(String s, String s1, String s2) {
        StringBuilder StringBuilder = new StringBuilder();
        int i = s1.length();
        for (int j = 0; (j = s.indexOf(s1)) != -1; ) {
            StringBuilder.append(s, 0, j).append(s2);
            s = s.substring(j + i);
        }

        StringBuilder.append(s);
        return StringBuilder.toString();
    }

    public static String replaceTag(String value, String tagStr, String subStr) {
        StringBuilder strBuffer = new StringBuilder();
        int count = 1;
        if (value == null || tagStr == null || subStr == null) {
            return value;
        }
        int len = tagStr.length();
        for (int j = 0; (j = value.indexOf(tagStr)) != -1; ) {
            if (count % 2 == 0) {
                strBuffer.append(subStr);
            } else {
                strBuffer.append(value, 0, j);
            }
            value = value.substring(j + len);
            count++;
        }

        strBuffer.append(value);
        return strBuffer.toString();
    }

    public static String getTagContent(String value, String tag) {
        String out = "";
        if (value != null && !value.isEmpty()) {
            int indexNum = value.indexOf(tag);
            if (indexNum != -1) {
                value = value.substring(indexNum + tag.length());
                indexNum = value.indexOf(tag);
                if (indexNum != -1) {
                    out = value.substring(0, indexNum);
                } else {
                    out = value;
                }
            }
        }
        return out;
    }

    public static String formatTag(String tag) {
        String returnTag = tag;
        if (returnTag != null) {
            returnTag = "<!--%" + returnTag + "%-->";
        }
        return returnTag;
    }

    public static String htmlEncode(String value) {
        if (value == null) {
            return "";
        }
        StringBuilder out = new StringBuilder();
        for (int i = 0; i < value.length(); i++) {
            out.append(emitQuote(value.charAt(i)));
        }

        return out.toString();
    }

    private static String emitQuote(char c) {
        String ls_Out = null;
        if (c == '&') {
            ls_Out = "&amp;";
        } else if (c == '"') {
            ls_Out = "&quot;";
        } else if (c == '<') {
            ls_Out = "&lt;";
        } else if (c == '>') {
            ls_Out = "&gt;";
        } else {
            ls_Out = String.valueOf(c);
        }
        return ls_Out;
    }

    public static String encodeParam(String param) {
        if (param == null) {
            return "";
        }
        Base64Encoder base64Encoder = new Base64Encoder();
        return base64Encoder.encode(param);
    }

    public static String decodeParam(String param) {
        try {
            param = URLDecoder.decode(param, "GBK");
        } catch (UnsupportedEncodingException e) {
            //已知GBK是支持的，因此封装异常
        }
        Base64Encoder base64Encoder = new Base64Encoder();
        if (param == null || param.trim().equals("null")) {
            return "";
        }
        param = base64Encoder.decode(param);
        return param;
    }

    public static String chinese2uicode(String chi) {

        StringBuilder b = new StringBuilder();
        char[] letter = {'A', 'B', 'C', 'D', 'E', 'F'};
        for (int i = 0; i < chi.length(); i++) {
            int ch0 = chi.charAt(i);
            if (ch0 > 255) {
                for (int j = 3; j >= 0; j--) {
                    int ch = ((ch0 >>> (j * 4)) & 0x000f);
                    if (ch < 10) {
                        b.append(ch);
                        continue;
                    }
                    b.append(letter[ch - 0x0a]);
                }
                b.append(";");
                continue;
            }
            b.append(chi.charAt(i));
        }

        return b.toString();
    }

    /**
     * 按格式生成序号，如0001,0002...9999
     * 如果结果位数超过指定的位数，则截去左侧多出的位数
     *
     * @param num   序号号码
     * @param scale 位数
     * @return 按位数格式化的序号，如0019
     * @deprecated 因方法名称不准确，拟弃用，以formatNumber代替
     */
    public static String buildSerial(int num, int scale) {
        return formatNumber(num, scale);
    }

    /**
     * 按格式生成序号，如0001,0002...9999
     * 如果结果位数超过指定的位数，则截去左侧多出的位数
     *
     * @param num   序号号码
     * @param scale 位数
     * @return 按位数格式化的序号，如0019
     * @deprecated 因方法名称不准确，拟弃用，以formatNumber方法代替
     */
    public static String buildSerial2(int num, int scale) {
        return formatNumber(num, scale);
    }

    /**
     * 按格式生成序号，如0001,0002...9999
     * 如果结果位数超过指定的位数，则截去左侧多出的位数
     *
     * @param number 待格式化的号码
     * @param scale  位数
     * @return 按位数格式化的序号，如0019
     */
    public static String formatNumber(Number number, int scale) {
        // 得到一个NumberFormat的实例
        NumberFormat nf = NumberFormat.getInstance();
        // 设置是否使用分组
        nf.setGroupingUsed(false);
        // 设置最大整数位数
        nf.setMaximumIntegerDigits(scale);
        // 设置最小整数位数
        nf.setMinimumIntegerDigits(scale);
        // 输出格式化字符串
        return nf.format(number);
    }

    /**
     * 补齐不足长度
     * 如果长度小于或等于0，则以数字本身长度返回字符串
     *
     * @param length 长度
     * @param number 数字
     * @return String
     */
    public static String complement(int length, int number) {
        if (length <= 0) {
            return String.valueOf(number);
        }
        String f = "%0" + length + "d";
        return String.format(f, number);
    }

    /**
     * 补齐不足长度，当长度为0，+1
     *
     * @param length 长度
     * @param number 数字
     * @return String
     */
    public static String incrComplement(int length, int number) {
        if (length < 0) {
            throw new IllegalArgumentException("长度不合法：" + length + ",应大于-1");
        }
        length = Math.max(1, length);
        return String.format("%0" + length + "d", number);
    }

    /**
     * 将异常栈信息转化成字符串
     *
     * @param t
     * @return String
     */
    public static String stackTrace(Throwable t) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(out);
        PrintWriter writer = new PrintWriter(ps);
        t.printStackTrace(writer);
        writer.flush();
        return out.toString();
    }

    public static String chooseNotEmpty(String str, String defaultStr) {
        return StrUtil.isTrimEmpty(str) ? defaultStr : str.trim();
    }

    /**
     * 根据给定长度，将给定字符串截取为多个部分
     *
     * @param str 字符串
     * @param len 每一个小节的长度
     * @return 截取后的字符串数组
     */
    public static String[] splitByLength(String str, int len) {
        int partCount = str.length() / len;
        int lastPartCount = str.length() % len;
        int fixPart = 0;
        if (lastPartCount != 0) {
            fixPart = 1;
        }

        String[] strs = new String[partCount + fixPart];
        for (int i = 0; i < partCount + fixPart; i++) {
            if (i == partCount + fixPart - 1 && lastPartCount != 0) {
                strs[i] = str.substring(i * len, i * len + lastPartCount);
            } else {
                strs[i] = str.substring(i * len, i * len + len);
            }
        }
        return strs;
    }

    /**
     * 以指定的分隔符连接对象数组中的所有不为空的对象的(toString())字符串
     *
     * @param delimiter: 分隔符
     * @param objs       对象数组
     * @return String
     * @date 2024/1/17 下午10:25
     */
    public static String join(String delimiter, Object... objs) {
        return Arrays.stream(objs).filter(Objects::nonNull).map(Object::toString).collect(Collectors.joining(delimiter));
    }

    public static void main(String[] args) {
        System.out.println(clearWhiteSpace("2016年　　　05月"));


    }
}
